/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.service.security.securityprovider;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.apache.log4j.Logger;

/**
 * Created on Apr 16, 2005
 * 
 * @author Harshawardhan Gadgil (hgadgil@grids.ucs.indiana.edu)
 */

public class KeyToolFacade {

    static Logger log = Logger.getLogger("KeyToolFacade");

    //
    // keytool -printcert -file root.cer

    /**
     * Generates a key for the specified client, using the specified
     * distinguished name
     * 
     * @param clientID -
     *            Client Alias
     * @param DNAME -
     *            DN of the client
     * @param validityDays -
     *            Days for which the certificate should be valid
     */
    public static void GenerateKey(CertificateManager certMan, String clientID,
            String DNAME, String validityDays) {

        // keytool -genkey -alias ROOT -keyalg RSA -keystore KEYSTORE -storepass
        // passpass -dname "CN=ROOT Provider,OU=CGL,O=Indiana
        // University,L=Bloomington,C=US" -validity days

        log.info("Generating Keypair for: " + clientID);

        String[] genkey = { "keytool", "-genkey", "-keystore",
                certMan.KEYSTORE, "-storetype", certMan.KEYSTORE_TYPE,
                "-storepass", certMan.KEYSTORE_PASSWORD, "-keypass",
                certMan.KEYSTORE_PASSWORD, "-alias", clientID, "-keyalg",
                certMan.KEY_ALGORITHM, "-dname", DNAME, "-validity",
                validityDays };

        executeKeyTOOLCommand(genkey);
    }

    /**
     * Generates a self signed certificate
     * 
     * @param clientID -
     *            ALias of client requesting the certificate
     * @param DNAME -
     *            Distinguished name of client
     * @param validity -
     *            Validity of certificate in days
     */
    public static void GenerateSelfCertifiedCertificate(
            CertificateManager certMan, String clientID, String DNAME,
            String validity) {
        // keytool -selfcert -alias ROOT -keyalg RSA -keystore KEYSTORE
        // -storepass
        // passpass -dname "CN=ROOT Provider,OU=CGL,O=Indiana
        // University,L=Bloomington,C=US"

        String[] genSelfCert = { "keytool", "-selfcert", "-keystore",
                certMan.KEYSTORE, "-storetype", certMan.KEYSTORE_TYPE,
                "-storepass", certMan.KEYSTORE_PASSWORD, "-keypass",
                certMan.KEYSTORE_PASSWORD, "-alias", clientID, "-keyalg",
                certMan.KEY_ALGORITHM, "-dname", DNAME, "-validity", validity };

        executeKeyTOOLCommand(genSelfCert);
    }

    public static String GenerateCertificateRequest(CertificateManager certMan,
            String clientID) {
        // keytool -keystore KEYSTORE -storepass passpass -certreq -file e1.csr
        // -alias e1

        log.info("Generating Ceritifcate Sign Request for: " + clientID);

        String outputFileName = certMan.KEYSTORE_PATH + "/" + clientID + ".csr";

        String[] genCertReq = { "keytool", "-certreq", "-keystore",
                certMan.KEYSTORE, "-storepass", certMan.KEYSTORE_PASSWORD,
                "-alias", clientID, "-file", outputFileName };

        executeKeyTOOLCommand(genCertReq);

        return outputFileName;
    }

    public static void ImportCertificate(CertificateManager certMan,
            String clientID, String importFilePath) {
        // keytool -import -alias cn -file resp.pem -keypass passpass -keystore
        // KEYSTORE -storepass passpass -noprompt

        String[] importCmd = { "keytool", "-import", "-keystore",
                certMan.KEYSTORE, "-storepass", certMan.KEYSTORE_PASSWORD,
                "-trustcacerts", "-noprompt", "-alias", clientID, "-file",
                importFilePath };

        executeKeyTOOLCommand(importCmd);
    }

    public static void ExportCertificate(CertificateManager certMan,
            String clientID, String certificatePath) {
        // keytool -export -alias cn -file resp.pem -keypass passpass -keystore
        // KEYSTORE -storepass passpass

        String[] exportCmd = { "keytool", "-export", "-keystore",
                certMan.KEYSTORE, "-storepass", certMan.KEYSTORE_PASSWORD,
                "-alias", clientID, "-file", certificatePath };

        executeKeyTOOLCommand(exportCmd);
    }

    public static void DeleteCertificate(CertificateManager certMan,
            String clientID) {
        // keytool -keystore NBKeyStore.keys -storepass passpass -keypass
        // passpass
        // -delete -alias cgl-entity-1

        String[] deleteCmd = { "keytool", "-delete", "-keystore",
                certMan.KEYSTORE, "-storepass", certMan.KEYSTORE_PASSWORD,
                "-alias", clientID };

        executeKeyTOOLCommand(deleteCmd);
    }

    /**
     * Executes the keytool command
     * 
     * @param cmd
     */
    private static void executeKeyTOOLCommand(String[] cmd) {

        String cmdStr = "";
        for (int i = 0; i < cmd.length; i++) {
            cmdStr += cmd[i] + " ";
        }

        log.info("Executing " + cmdStr);

        Runtime rt = Runtime.getRuntime();
        try {
            Process proc = rt.exec(cmd);
            String x;

            BufferedReader in = new BufferedReader(new InputStreamReader(proc
                    .getInputStream()));
            while ((x = in.readLine()) != null)
                System.out.println(x);

            in = new BufferedReader(
                    new InputStreamReader(proc.getErrorStream()));
            while ((x = in.readLine()) != null)
                System.out.println(x);

            proc.waitFor();
            log.info("Execution Successful");
        } catch (Exception e) {
            log.warn("ERROR", e);
        }
    }

}